// 基于下面提供的代码，完成后续的四个练习
// 代码见support.js
const fp = require('lodash/fp')
const { Maybe, Container } = require('./support')

// 练习1 - 使用fp.add(x,y)和fp.map(f,x)创建一个能让functor里的值增加的函数ex1
let maybe = Maybe.of([5, 6, 1])
let ex1 = fp.curry((n, target) => {
  return target && target.map ? target.map(fp.map(fp.add(n))) : target
})

// 测试代码
console.log('原始maybe实例:', maybe)
console.log('数组中各项值加1:', ex1(1)(maybe))
console.log('数组中各项值加1:', ex1(1)(maybe))
console.log('数组中各项值加3:', ex1(3, maybe))
console.log('数组中各项值加5:', ex1(5, maybe))
// 特殊情况测试
// 1.空数组
maybe = Maybe.of([])
console.log('原始maybe实例:', maybe)
console.log('数组中各项值加1:', ex1(1)(maybe))
// 2.null or undefined
maybe = Maybe.of()
console.log('原始maybe实例:', maybe)
console.log('数组中各项值加1:', ex1(1)(maybe))

//
// 练习2 - 实现一个函数ex2，能够使用fp.first()获取列表的第一个元素
let xs = Container.of(['do', 'ray', 'me', 'fa', 'so', 'la', 'ti', 'do'])
let ex2 = (target) => {
  return target && target.map ? target.map(fp.first) : target
}
// 测试代码
console.log('call ex2:', ex2(xs))

//
// 练习3 - 实现一个函数ex3，使用safeProp()和fp.first()找到user的名字的第首字母
let safeProp = fp.curry(function (x, o) {
  return Maybe.of(o[x])
})
let user = { id: 2, name: 'Albert' }
let ex3 = (target) => {
  return target ? safeProp('name')(target).map(fp.first) : null
}
// 测试代码
console.log('call ex3:', ex3(user))

//
// 练习4 - 使用Maybe重写ex4，不要有if语句
let ex4 = function (n) {
  if (n) {
    return parseInt(n)
  }
}

let ex4Rewrite = (n) => {
  return Maybe.of(n).map(parseInt)
}

//测试代码
console.log('call ex4:', ex4(5))
console.log('call ex4:', ex4('r'))
console.log('call ex4:', ex4())

console.log('call ex4Rewrite:', ex4Rewrite(5))
console.log('call ex4Rewrite:', ex4Rewrite('r'))
console.log('call ex4Rewrite:', ex4Rewrite())
